/*
 * @Date: 2022-11-07 10:42:05
 * @LastEditors: 春贰
 * @gitee: https://gitee.com/chun22222222
 * @github: https://github.com/chun222
 * @Desc:
 * @LastEditTime: 2023-11-28 11:29:28
 * @FilePath: \server\system\service\SysService\user.go
 */
/*
 * @Date: 2022-02-25 16:37:23
 * @LastEditors: 春贰
 * @gitee: https://gitee.com/chun22222222
 * @github: https://github.com/chun222
 * @Desc:
 * @LastEditTime: 2023-04-20 12:48:55
 * @FilePath: \server\system\service\SysService\user.go
 */

package SysService

import (
	"time"

	"go-easy-dashboard/system/core/config"
	"go-easy-dashboard/system/core/db"
	"go-easy-dashboard/system/core/request"
	"go-easy-dashboard/system/model/CommonModel"
	"go-easy-dashboard/system/model/DbModel"
	"go-easy-dashboard/system/util/ldapUtil"
	"go-easy-dashboard/system/util/sys"
	"gorm.io/gorm"

	"go-easy-dashboard/system/model/RequestModel"
)

type UserService struct{}

//判断用户是否具备该角色
func (userService *UserService) CheckRole(username string, rolename string) bool {
	err, list := userService.Roles(username)
	if err != nil {
		return false
	}
	for _, v := range list {
		if v.RoleName == rolename {
			return true
		}
	}
	return false
}

//新增
func (userService *UserService) Add(info *DbModel.SysUser) (err error) {
	info.Password = sys.EncryptPass(info.Password)
	temNow := time.Now()
	info.PassUpdate = &temNow
	result := db.Instance().Create(info)
	return result.Error
}

//修改
func (userService *UserService) Update(info *DbModel.SysUser) (err error) {
	var user DbModel.SysUser
	if err := db.Instance().First(&user, info.LoginName).Error; err != nil {
		return err
	}
	//忽略字段
	if info.Password == "" {
		return db.Instance().Omit("CreatedAt", "Password", "PassUpdate").Save(info).Error
	} else {
		info.Password = sys.EncryptPass(info.Password)
		temNow := time.Now()
		info.PassUpdate = &temNow
		return db.Instance().Omit("CreatedAt").Save(info).Error
	}

}

//分页列表
func (userService *UserService) List(info RequestModel.SysUserSearch) (err error, list interface{}, total int64) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)

	db := db.Instance().Model(&DbModel.SysUser{})
	//动态查询条件
	request.GenWhere(info, db)
	var userList []DbModel.SysUser
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Omit("Photo", "RecognitionCode").Limit(limit).Offset(offset).Find(&userList).Error
	return err, userList, total
}

//用户详情
func (userService *UserService) Detail(id uint) (err error, user DbModel.SysUser) {
	err = db.Instance().First(&user, id).Error
	return
}

//删除
func (userService *UserService) Remove(info CommonModel.Ids) (err error) {

	return db.Instance().Transaction(func(tx *gorm.DB) error {
		tx.Exec("set autocommit=0")
		// 使用 'tx' 而不是 'db'
		if err := tx.Where("user_id in ?", info.Ids).Delete(&DbModel.SysUserRole{}).Error; err != nil {
			// 返回任何错误都会回滚事务
			return err
		}
		if err := tx.Where("user_id in ?", info.Ids).Delete(&DbModel.SysUserPermission{}).Error; err != nil {
			// 返回任何错误都会回滚事务
			return err
		}
		if err := tx.Delete(&DbModel.SysUser{}, info.Ids).Error; err != nil {
			// 返回任何错误都会回滚事务
			return err
		}
		// 返回 nil 提交事务
		return nil
	})

}

//获取已经具备的权限
func (userService *UserService) Permissions(id uint) (err error, list interface{}) {
	var dataList []DbModel.SysUserPermission
	err = db.Instance().Preload("Permission").Where("user_id = ?", id).Find(&dataList).Error
	return err, dataList
}

//分配权限
func (userService *UserService) SetPermissions(r RequestModel.SysSetPermissions) (err error) {
	var dataList []DbModel.SysUserPermission
	for _, v := range r.CheckedKeys {
		dataList = append(dataList, DbModel.SysUserPermission{LoginName: r.Name, PermissionName: v, Checked: 1})
	}
	for _, v := range r.HalfCheckedKeys {
		dataList = append(dataList, DbModel.SysUserPermission{LoginName: r.Name, PermissionName: v, Checked: 0})
	}

	return db.Instance().Transaction(func(tx *gorm.DB) error {
		tx.Exec("set autocommit=0")
		// 使用 'tx' 而不是 'db'
		if err := tx.Where("login_name = ?", r.Name).Delete(&DbModel.SysUserPermission{}).Error; err != nil {
			// 返回任何错误都会回滚事务
			return err
		}
		if len(dataList) > 0 {
			if err := tx.Create(&dataList).Error; err != nil {
				return err
			}
		}
		// 返回 nil 提交事务
		return nil
	})
}

//获取已经分配角色
func (userService *UserService) Roles(user_name string) (err error, list []DbModel.SysUserRole) {
	var dataList []DbModel.SysUserRole
	err = db.Instance().Preload("Roles").Where("user_name = ?", user_name).Find(&dataList).Error
	return err, dataList
}

//给用户分配角色
func (userService *UserService) SetRoles(r RequestModel.SysSetRoles) (err error) {

	var dataList []DbModel.SysUserRole
	for _, v := range r.RoleNames {
		dataList = append(dataList, DbModel.SysUserRole{UserName: r.LoginName, RoleName: v})
	}

	return db.Instance().Transaction(func(tx *gorm.DB) error {
		tx.Exec("set autocommit=0")
		// 使用 'tx' 而不是 'db'
		if err := tx.Where("user_name  = ?", r.LoginName).Delete(&DbModel.SysUserRole{}).Error; err != nil {
			// 返回任何错误都会回滚事务
			return err
		}
		if len(dataList) > 0 {
			if err := tx.Create(&dataList).Error; err != nil {
				return err
			}
		}

		// 返回 nil 提交事务
		return nil
	})

}

//同步LDAP用户
func (userService *UserService) SyncLdapUser() (err error) {
	c := ldapUtil.LdapConfig{
		Host:   config.Instance().Ldap.Host,
		User:   config.Instance().Ldap.AdminUser,
		Pass:   config.Instance().Ldap.AdminPass,
		BaseDn: config.Instance().Ldap.BaseDn,
	}
	err, l := c.Users()
	if err != nil {
		return
	}

	//同步用户
	for _, lu := range l {
		temUser := DbModel.SysUser{
			LoginName: lu.Name,
			UserName:  lu.Name,
			Email:     lu.Email,
		}
		// 直接创建，索引会约束
		db.Instance().Create(&temUser)
	}
	return nil
}
